//////////////////////////////////////////////////////////////////////////
//Copyright (c) 2011, linlin liu
//All rights reserved.
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions are met:
//* Redistributions of source code must retain the above copyright
//notice, this list of conditions and the following disclaimer.
//* Redistributions in binary form must reproduce the above copyright
//notice, this list of conditions and the following disclaimer in the
//documentation and/or other materials provided with the distribution.
//* Neither the name of the <organization> nor the
//names of its contributors may be used to endorse or promote products
//derived from this software without specific prior written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
//DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
//DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
//ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//////////////////////////////////////////////////////////////////////////

#include "amf0/amf0_list.h"
#include "amf0/amf0.h"

#include <sstream>
#include <boost/foreach.hpp>

typedef std::vector<amf::amf_data_ptr> amf_list_t;

void amf::amf_list::add(amf::amf_data_ptr as)
{
    m_list.push_back(as);
}

void amf::amf_list::encode(char* data) const
{
    char* ptr = data;

    BOOST_FOREACH(const amf::amf_data_ptr & item, m_list)
    {
        amf_item::encode(ptr, item);

        ptr += item->get_size() + 1;
    }
}

boost::int32_t amf::amf_list::decode(const char* data, boost::uint32_t quota)
{
    boost::uint32_t left_quota = quota;

    const char* ptr = data;

    while (left_quota > 0)
    {
        amf::amf_data_ptr item = amf_item::decode(ptr, left_quota);

        if (item->get_type() == AMF_TYPE_UNSUPPORTED)
        {
            return AMF_DECODE_FAILED;
        }

        m_list.push_back(item);

        boost::uint32_t item_size = item->get_size() + 1;

        ptr += item_size;
        left_quota -= item_size;
    }

    return get_size();
}

boost::uint32_t amf::amf_list::get_size(void) const
{
    boost::uint32_t total_size = 0;

    BOOST_FOREACH(const amf::amf_data_ptr & item, m_list)
    {
        total_size += item->get_size();
    }

    return total_size + m_list.size();
}

boost::uint32_t amf::amf_list::count() const
{
    return m_list.size();
}

std::string amf::amf_list::to_string() const
{
    std::ostringstream rt;

    BOOST_FOREACH(const amf::amf_data_ptr & item, m_list)
    {
        rt << item->to_string() << std::endl;
    }

    return rt.str();
}

const amf::amf_data_ptr amf::amf_list::at(int pos) const
{
    return m_list.at(pos);
}